import time
from threading import Event
from ...utils.workflow_manager import WorkFlow
from ...utils.loggers import dev_logger, prod_logger, record_logger
from ...utils.utils import singleton



@singleton
class RemoteStartWorkFlow(WorkFlow):
    
    unit_debug = True
    step1_cycle_event = Event()
    step1_cycle_flag = False
    step2_cycle_event = Event()
    step2_cycle_flag = False
    def stepReset(self):
        # print('RemoteStartWorkFlow-----stepReset ---- 待补充置零步数的清理工作')
        self.stepOverFlagInit()
        self.setStep(0)

    def handleStep0(self):
        self.parentView.userWindowFrame3StepsFrameStep0Frm_btn1.configure(state='normal')

        # print('step0....')
        # 此处通过按钮触发
        if self.step0OverFlag:

            self.parentView.userWindowFrame3StepsFrameStep0Frm_btn1.configure(state='disabled')
            self.nextStep() 

    def cycle_handle_start(self, handle, cycle_event, cycle_flag, cycle_time=2, handle_info=None):
        '''
        cycle_event:线程event
        cycle_flag: step中对应event的flag
        cycle_time: 循环工作的间隔时间
        handle：循环工作的函数，必要时用lambda形式
        '''
        def wrapper():
            while True:
                time.sleep(cycle_time)
                # 如果Event被set了，就退出循环
                if cycle_event.is_set():
                    # [ ]: 此处做一些收尾清理工作
                    # step1_cycle_flag = False，因为下一次还要用
                    cycle_flag = False
                    # 清除event，因为下一次还要用
                    # event.clear()
                    cycle_event.clear()
                    break

                # 循环执行主函数
                handle()

                if handle_info:
                    dev_logger.debug(handle_info)

        return wrapper
    def cycle_handle_stop(self, cycle_event,handle_info=None):
        # 通过event设置停止子线程中的cycle
        cycle_event.set()

        if handle_info:
            dev_logger.debug(handle_info)

    def handleStep1(self):
        #[ ]:信号意义？
        self.parentView.display_log('step1, 发送0x724:02 10 03 00 00 00 00 00')
        #[ ]:信号意义？
        self.parentView.display_log('step1, 发送0x724:03 28 03 01 00 00 00 00')
        if not self.unit_debug:
            self.parentView.sendMsg_checkRecv(sendId=0x724, sendData='0210030000000000')
            self.parentView.sendMsg_checkRecv(sendId=0x724, sendData='0328030100000000')


        if not self.step1_cycle_flag:
            # 诊断信号持续发送，保证控制器处于诊断模式
            # 主函数
            def handle():
                # print('step1 handle running......')
                self.parentView.display_log('step1----每2S循环发送控制器诊断信号....')
                if not self.unit_debug:
                    self.parentView.sendMsg_checkRecv(sendId=0x724, sendData="023E000000000000")
                
            self.pool.submit(self.cycle_handle_start(handle, self.step1_cycle_event, self.step1_cycle_flag, handle_info='每隔2S发送诊断信号'))

            # 此处置True，保证不会多次重复启动
            self.step1_cycle_flag = True

        self.step1OverFlag=True
        if self.step1OverFlag:
            self.nextStep() 

    def handleStep2(self):
        # print("step2")
        self.parentView.display_log('step2,循环发送模拟油量信号...')
        # 如果没有启动循环，就启动循环
        if not self.step2_cycle_flag:
            # self.pool.submit(self.step2_cycle_handle)

            def handle():

                self.parentView.display_log('step2----每1s循环发送剩余油量模拟信号....')
                if not self.unit_debug:
                    self.parentView.display_log("sendId=0x621, sendData='000C000000000000'")
                    self.parentView.sendMsg_checkRecv(sendId=0x621, sendData='000C000000000000')


            self.pool.submit(self.cycle_handle_start(handle, self.step2_cycle_event, self.step2_cycle_flag, cycle_time=1, handle_info='每隔1S发送剩余油量信号'))

            # 此处置True，保证不会多次重复启动
            self.step2_cycle_flag = True

        # 此处永远正常通过
        self.step2OverFlag = True
        if self.step2OverFlag:
            self.nextStep() 

    def handleStep3(self):
        '''
        监视发动机启动的信号【0x280:0000000000040000】
        监视到之后就停发油量的信号,1003,2800
        '''
        # [ ] 发动机启动信号，有效位数是那几位？还是必须全部完全匹配?
        self.parentView.display_log('step3,监视发动机信号，停发油量信号，停发控制器诊断信号')
        # 上个线程锁，避免同时对deque读取时，产生冲突
        with self.mainView.recvMsgDequeLock:
            # 将deque中的信息转换到临时列表，以备处理
            recvMsgs = list(self.mainView.recvMsgDeque)
            # 信息转换完成后，将队列清空，重新接收数据
            self.mainView.recvMsgDeque.clear()
        self.parentView.display_log(f'接收到缓存中的信息---{len(recvMsgs)}---条')

        def test_finish():
            # 确认收到信号后的执行动作
            self.parentView.display_log('收到发动机启动信号')

            # 监视到之后就停发油量的信号,发送1003,2800
            # 停发油量信号
            self.cycle_handle_stop(self.step2_cycle_event, 'step3----循环油量模拟信号停止发送')
            
            self.parentView.display_log('step3, 发送0x724:02 10 03 00 00 00 00 00')
            #[ ]:信号意义？
            self.parentView.display_log('step3, 发送0x724:03 28 00 01 00 00 00 00')
            if not self.unit_debug:
                self.parentView.sendMsg_checkRecv(sendId=0x724, sendData='0210030000000000')
                self.parentView.sendMsg_checkRecv(sendId=0x724, sendData='0328000100000000')

            # 停发诊断信号
            self.cycle_handle_stop(self.step1_cycle_event, 'step3----循环诊断信号停止发送...')

            #step3可通过
            self.step3OverFlag = True
        # 对转存的数据进行处理
        hope_id = 0x280
        hope_data = '0000000000040000'
        for msg in recvMsgs:
            # 
            # msg的格式定义是： RecvMsg = collections.namedtuple("RecvMsg", ["id", "data"])
            # id 和 data 都是字符串类型，需要转换后进行对比
            # [ ]对比方式需要确认
            cur_id = int(msg.id, 16)
            if cur_id != hope_id:
                continue
            else:
                cur_data = msg.data
                # 只要核对第6个字符的内容即可
                if cur_data[10:12] == hope_data[10:12]:
                    test_finish()
                    break


        if self.unit_debug:
            test_finish()

        if self.step3OverFlag:
            self.nextStep() 
    
    def stepOverFlagInit(self):
        '''
        初始化步数Flag信号
        '''
        stepCounts = self.stepCounts
        for i in range(stepCounts):
            self.resetStepOverFlag(i)

    def stepEventInit(self):
        self.step2_cycle_event.clear()
        self.step1_cycle_event.clear()
    
    # def stepCycleFlagInit(self):
    # step_cycle_flag 与 step_cycle_event 是配对工作，event被set时候，程序会把flag给复位了，所以此处暂时不启用。除非后续发现bug，再考虑启用
    #     self.step1_cycle_flag = False
    #     self.step2_cycle_flag = False
        
    def handleStep4(self):
        time.sleep(1)
        print("step4")
        self.stepOverFlagInit()
        self.stepEventInit()
        self.setStep(0)
    
    def refreshMainViewStep(self):
        # print('refreshMainViewStep ........')
        # print(self.mainView, 'self.mainView')
        pass
        self.parentView.refreshStep(self.getStep())

